/*
 * @Author: 0x9DEFA478
 * @Date: 2025-08-03 23:24:13
 * @LastEditTime: 2025-10-17 23:32:42
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * 
 */
#include "HMakeTargetTask_C_CPP.hpp"
#include "HMakePath.hpp"
#include "Utility/H_Path.hpp"
#include "SystemUtility/C_LocalUTF8.hpp"
#include "SystemUtility/C_VirtualTerminal_Macro.h"
#include <queue>
#include <sstream>
#include <fstream>




namespace HMake{

  using namespace std::literals::string_literals;

  static H::size ReadCompilerTool(const TargetConfig::ConstPointer& targetConfig,std::list<std::string>& list,const std::string& ValueName,const std::string& prefix){
    H::size r;

    auto vallist=TargetTask::ReadValueArray(targetConfig,ValueName);

    if(!vallist.empty()){
      *vallist.begin()=prefix+(*vallist.begin());
    }
    r=vallist.size();
    list.splice(list.end(),vallist);
    return r;
  }
  
  static std::list<std::pair<H::Path,H::Path>> GetBuildPathFromSrcPath(const std::list<std::string> SrcList,const std::string& Directory,const std::string& AbsoluteDirectory){
    std::list<std::pair<H::Path,H::Path>> r;
    
    auto relPath=H::Path(Directory);
    auto absPath=H::Path(AbsoluteDirectory);

    for(auto& Item:SrcList){
      auto path=H::Path(Item);
      if(path.IsRelative()){
        r.emplace_back(path.DiscardRelative(),(relPath+path).DiscardRelative());
      }else{
        r.emplace_back(path.DiscardRelative(),(absPath+path.ToRelative()).DiscardRelative());
      }
    }

    return r;
  }

  H::Tree::RedBlack<H::Path,H::Tree::RedBlack<H::Path,int>> ReadDependencyMakeFile(const std::string& headerDependencyFilePath){
    H::Tree::RedBlack<H::Path,H::Tree::RedBlack<H::Path,int>> depMap;
    std::ifstream file;

    file.open(H::UTF8_To_LocalSystem(headerDependencyFilePath));

    if(!file.is_open()){
      return depMap;
    }

    try{
      bool IsFindDep=false;
      H::Path target;
      std::stringstream ss;
      bool ssIsEnd=false;

      auto AddDep=[&depMap,&target,&ss]{
        auto str=ss.str();
        if(str.length()>0){
          auto depPath=H::Path(ss.str()).DiscardRelative();
          ss=std::stringstream();

          depMap[target].Insert(depPath,0);
        }
      };

      while(!file.eof()){
        std::string lineStr;
        std::getline(file,lineStr);
        
        lineStr=H::LocalSystem_To_UTF8(lineStr);

        std::size_t length=lineStr.length();

        while(length>0){
          char c=lineStr[length-1];
          if((c!='\r')&&(c!='\n')){
            break;
          }
          length--;
        }

        if(length<1){
          continue;
        }

        bool IsEsc=false;
        for(std::size_t i=0;i<length;i++){
          char c=lineStr[i];

          if((!IsEsc)&&(c=='\\')){
            IsEsc=true;
            continue;
          }

          if(c==' '){
            if(IsEsc){
              ss<<c;
              IsEsc=false;
              continue;
            }

            if(IsFindDep){
              AddDep();
            }else{
              ssIsEnd=true;
            }
            continue;
          }

          IsEsc=false;

          if(IsFindDep){
            ss<<c;
          }else{
            if(c==':'){
              target=H::Path(ss.str()).DiscardRelative();
              ssIsEnd=false;
              ss=std::stringstream();
              IsFindDep=true;
            }else{
              if(!ssIsEnd){
                ss<<c;
              }
            }
          }

        }

        if(!IsEsc){
          if(IsFindDep){
            AddDep();
          }

          IsFindDep=false;
          ss=std::stringstream();
          ssIsEnd=false;
        }
      }

      file.close();
    }catch(const std::exception& e){
      file.close();
      throw;
    }
    return depMap;
  }

  std::list<DependencyChain::Item::Pointer> MakeHeaderDependency(const std::string& headerDependencyFilePath,const H::Path& SourcePath,const std::string& targetFilePath){
    std::list<DependencyChain::Item::Pointer> r;
    auto depMap=ReadDependencyMakeFile(headerDependencyFilePath);

    if(depMap.Empty()){
      return r;
    }

    std::queue<H::Path> queue;

    queue.push(targetFilePath);
    while(!queue.empty()){
      auto& val=queue.front();

      auto res=depMap.Find(val);
      if(res==depMap.end()){
        queue.pop();
        continue;
      }

      for(auto& Item:res->Data()){
        auto path=Item.Key().DiscardRelative();

        if(path==SourcePath){
          continue;
        }

        r.emplace_back(DependencyItem_Input::New(path.String()));
        queue.push(path);
      }

      queue.pop();
    }

    for(auto& Item:r){
      try{
        Item->UpdateTargetStatus();
      }catch(const std::runtime_error&){
        Item->ForceSetNewExist();
      }
    }

    
    //debug
    // std::ofstream file;
    // file.open(H::UTF8_To_LocalSystem(headerDependencyFilePath)+".dep",std::ios::out|std::ios::trunc);
    // for(auto& Item:r){
    //   file<<static_cast<DependencyItem_Input*>(Item.GetPointer())->TargetPath()<<"\n";
    // }
    // file.close();

    return r;
  }

  static std::string ArgAutoAddBackslash(const std::string& Arg){
    std::stringstream ss;

    for(auto& Item:Arg){
      if((Item==' ')||(Item=='\"')||(Item=='\\')){
        ss<<'\\';
      }
      ss<<Item;
    }

    return ss.str();
  }

  std::pair<int,std::string> CreateParamFile(const std::string& path,const std::list<std::string>& param){
    std::ofstream file;
    file.open(H::UTF8_To_LocalSystem(path),std::ios::out|std::ios::trunc);

    if(!file.is_open()){
      return {1,"文件\""+path+"\"打开失败"};
    }

    try{
      for(auto& Item:param){
        file<<H::UTF8_To_LocalSystem(ArgAutoAddBackslash(Item))<<"\n";
        if(!file){
          throw std::runtime_error("写入失败");
        }
      }
    }catch(const std::exception& e){
      file.close();
      return {1,"文件\""+path+"\"操作失败:"+e.what()};
    }

    file.close();
    return {0,""};
  }


  TargetTask_GCC::TargetTask_GCC(const TargetConfig::Pointer& targetConfig
    ,const DependencyChain::Item::Pointer& hmkFileDependency
    ,const std::string& cwd,const std::string& shell
    ,DependencyItem_Directory::Collection::Pointer& DirectoryCollection
    ,Log::Pointer& log
    ,AttributeMask Attribute)
    :TargetTask(targetConfig,shell,Attribute)
    ,hmkFileDependency(hmkFileDependency)
    ,DirectoryCollection(DirectoryCollection)
    ,log(log)
    ,cwd(cwd)
    ,io_encoding(DependencyItem_SystemProcess::Task_Process::IOEncoding::Local)
  {

#if defined(_WIN32)
    const char* io_encoding_name="HMake.Encoding.Compiling.Windows";
#elif defined(__linux__)
    const char* io_encoding_name="HMake.Encoding.Compiling.Linux";
#endif

    const char* io_encoding_name_Default="HMake.Encoding.Compiling";

    const Value* vp;
#if defined(_WIN32)||defined(__linux__)
    vp=targetConfig->FindValue(io_encoding_name);
    if((vp!=nullptr)&&(vp->Valid())&&(vp->ValueArray().Length()>0)){
      try{
        io_encoding=DependencyItem_SystemProcess::Task_Process::StringToIOEncoding(vp->ValueArray()[0]);
      }catch(const std::exception& e){
        throw std::runtime_error("$("s+io_encoding_name+")无效: "+e.what());
      }
    }else
#endif
    {
      vp=targetConfig->FindValue(io_encoding_name_Default);
      if((vp!=nullptr)&&(vp->Valid())&&(vp->ValueArray().Length()>0)){
        try{
          io_encoding=DependencyItem_SystemProcess::Task_Process::StringToIOEncoding(vp->ValueArray()[0]);
        }catch(const std::exception& e){
          throw std::runtime_error("$(HMake.Encoding.Compiling)无效: "s+e.what());
        }
      }
    }
  }

  TargetTask_GCC::~TargetTask_GCC(){}

  DependencyChain::Item::Pointer TargetTask_GCC::MakeTask(){
    DependencyChain::Item::Pointer root;
    
    TargetType=ReadValue(targetConfig,"HMake.Bin.Type");

    CompilerPrefix=ReadValue_WithDefault(targetConfig,"HMake.Compiler.Prefix");
    ReadCompilerTool(targetConfig,CC,"HMake.Compiler.CC",CompilerPrefix);
    ReadCompilerTool(targetConfig,CXX,"HMake.Compiler.CXX",CompilerPrefix);
    ReadCompilerTool(targetConfig,AS,"HMake.Compiler.AS",CompilerPrefix);
    ReadCompilerTool(targetConfig,LD,"HMake.Compiler.LD",CompilerPrefix);
    ReadCompilerTool(targetConfig,AR,"HMake.Compiler.AR",CompilerPrefix);

    auto Build_ObjectDirectory=ReadValue(targetConfig,"HMake.Build.ObjectDirectory");
    auto Build_ObjectDirectory_Absolute=ReadValue(targetConfig,"HMake.Build.ObjectDirectory.Absolute");
    auto Bin_Name=ReadValue(targetConfig,"HMake.Bin.Name");
    auto Bin_DirectoryStr=ReadValue(targetConfig,"HMake.Bin.Directory");

    auto C_FileList=GetBuildPathFromSrcPath(ReadValueArray(targetConfig,"HMake.SourceFile.C"),Build_ObjectDirectory,Build_ObjectDirectory_Absolute);
    auto CPP_FileList=GetBuildPathFromSrcPath(ReadValueArray(targetConfig,"HMake.SourceFile.CPP"),Build_ObjectDirectory,Build_ObjectDirectory_Absolute);
    auto ASM_FileList=GetBuildPathFromSrcPath(ReadValueArray(targetConfig,"HMake.SourceFile.ASM"),Build_ObjectDirectory,Build_ObjectDirectory_Absolute);
    auto OBJ_FileList=ReadValueArray(targetConfig,"HMake.SourceFile.OBJ");
    
    
    if(C_FileList.size()+CPP_FileList.size()+ASM_FileList.size()+(OBJ_FileList.size())<1){
      throw std::runtime_error("没有用于构建目标的文件");
    }

    auto Bin_Directory=H::Path(Bin_DirectoryStr).DiscardRelative();
    auto TargetPath=(Bin_Directory+Bin_Name).DiscardRelative();
    auto TargetPathStr=TargetPath.String();
    auto ArgFilePath=TargetPathStr+".arg";
    auto PostBuildMarkFilePath=TargetPathStr+".postbuild";
    auto BinDirectoryCreateTask=DirectoryCollection->Insert(Bin_Directory,"\e[" C_VT_F_Green "mCreate Directory\e[0m: "+Bin_Directory.String(),"SKIP [Create Directory "+Bin_Directory.String()+"]",log);
    BinDirectoryCreateTask->UpdateTargetStatus();

    std::list<DependencyChain::Item::Pointer> SrcDependency;

    auto AddSrcFile=[this,&C_FileList,&CPP_FileList,&ASM_FileList,&SrcDependency](std::list<std::string>& Args){

      for(auto& Item:C_FileList){
        SrcDependency.emplace_back(MakeSrcTask_CC_CXX_AS(Item.first,Item.second,SrcTaskType::CC));
        Args.emplace_back(Item.second.String()+".o");
      }

      for(auto& Item:CPP_FileList){
        SrcDependency.emplace_back(MakeSrcTask_CC_CXX_AS(Item.first,Item.second,SrcTaskType::CXX));
        Args.emplace_back(Item.second.String()+".o");
      }

      for(auto& Item:ASM_FileList){
        SrcDependency.emplace_back(MakeSrcTask_CC_CXX_AS(Item.first,Item.second,SrcTaskType::AS));
        Args.emplace_back(Item.second.String()+".o");
      }

    };


    DependencyChain::Item::Pointer ArgDependencyItem;
    if((TargetType=="Execute")||(TargetType=="DynamicLibrary")){

      //CompilerLD LD_OPT objlist -o outPath
      std::list<std::string> LD_Args;

      if(LD.empty()){
        throw std::runtime_error("HMake.Compiler.LD 无有效的值");
      }
      for(auto& Item:LD){
        LD_Args.emplace_back(Item);
      }

      {
        auto Args_Dep=ReadValueArray(targetConfig,"HMake.Linking.LD.Option");
        
        {
          auto linkScript=ReadValue_WithDefault(targetConfig,"HMake.Linking.LD.LinkScript");
          if(linkScript.length()>0){
            Args_Dep.emplace_back("-T"+linkScript);
          }
        }

        //SrcFile Obj
        AddSrcFile(Args_Dep);

        Args_Dep.splice(Args_Dep.end(),OBJ_FileList);

        {
          auto libPathList=ReadValueArray(targetConfig,"HMake.Linking.LD.LibPath");

          for(auto& Item:libPathList){
            Item="-L"+Item;
          }

          Args_Dep.splice(Args_Dep.end(),libPathList);
        }

        {
          auto libList=ReadValueArray(targetConfig,"HMake.Linking.LD.Lib");

          for(auto& Item:libList){
            Item="-l"+Item;
          }

          Args_Dep.splice(Args_Dep.end(),libList);
        }

        if(Args_Dep.size()<9){
          LD_Args.splice(LD_Args.end(),Args_Dep);
        }else{
          std::string skipLog;
          if((attribute&AttributeMask::IsPrintSkip)!=0U){
            skipLog="SKIP [Create "+ArgFilePath+"]";
          }
          ArgDependencyItem=DependencyItem_SystemProcess::New(ArgFilePath,DependencyItem_SystemProcess::Task_Thread::New(
            [ArgFilePath,Args_Dep](std::stringstream& SS,bool ioexclusive){
              auto res=CreateParamFile(ArgFilePath,Args_Dep);
              SS<<res.second;
              return res.first;
            }
          ),"",skipLog,log);
          ArgDependencyItem->UpdateTargetStatus();
          DependencyChain::AddDependency(ArgDependencyItem,hmkFileDependency);
          DependencyChain::AddDependency(ArgDependencyItem,BinDirectoryCreateTask);
          LD_Args.emplace_back("@"+ArgFilePath);
        }
      }

      if(TargetType=="DynamicLibrary"){
        LD_Args.emplace_back("-shared");
        LD_Args.emplace_back("-fPIC");
      }

      LD_Args.emplace_back("-o");
      LD_Args.emplace_back(TargetPathStr);
      
      std::string skipLog;
      std::string runLog;
      SetLogTag(
        runLog,"\e[" C_VT_F_Green "mLD\e[0m "+TargetPathStr,
        skipLog,"SKIP [LD "+TargetPathStr+"]",
        LD_Args
      );
      root=DependencyItem_SystemProcess::New(TargetPathStr,LD_Args,io_encoding,runLog,skipLog,log);
    }else if(TargetType=="StaticLibrary"){

      std::list<std::string> AR_Args;
      if(AR.empty()){
        throw std::runtime_error("HMake.Compiler.AR 无有效的值");
      }
      for(auto& Item:AR){
        AR_Args.emplace_back(Item);
      }
      
      AR_Args.emplace_back("-rcs");
      AR_Args.emplace_back(TargetPathStr);

      {
        std::list<std::string> Args_Dep;

        //SrcFile Obj
        AddSrcFile(Args_Dep);

        Args_Dep.splice(Args_Dep.end(),OBJ_FileList);

        if(Args_Dep.size()<9){
          AR_Args.splice(AR_Args.end(),Args_Dep);
        }else{
          std::string skipLog;
          if((attribute&AttributeMask::IsPrintSkip)!=0U){
            skipLog="SKIP [Create "+ArgFilePath+"]";
          }
          ArgDependencyItem=DependencyItem_SystemProcess::New(ArgFilePath,DependencyItem_SystemProcess::Task_Thread::New(
            [ArgFilePath,Args_Dep](std::stringstream& SS,bool ioexclusive){
              auto res=CreateParamFile(ArgFilePath,Args_Dep);
              SS<<res.second;
              return res.first;
            }
          ),"",skipLog,log);
          ArgDependencyItem->UpdateTargetStatus();
          DependencyChain::AddDependency(ArgDependencyItem,hmkFileDependency);
          DependencyChain::AddDependency(ArgDependencyItem,BinDirectoryCreateTask);
          AR_Args.emplace_back("@"+ArgFilePath);
        }
      }

      std::string skipLog;
      std::string runLog;
      SetLogTag(
        runLog,"\e[" C_VT_F_Green "mAR\e[0m "+TargetPathStr,
        skipLog,"SKIP [AR "+TargetPathStr+"]",
        AR_Args
      );
      root=DependencyItem_SystemProcess::New(TargetPathStr,AR_Args,io_encoding,runLog,skipLog,log);
    }else{
      throw std::runtime_error("HMake.Bin.Type 设置的类型不支持");
    }

    DependencyChain::AddDependency(root,ArgDependencyItem);
    DependencyChain::AddDependency(root,hmkFileDependency);
    
    DependencyChain::AddDependency(root,BinDirectoryCreateTask);
    if(ArgDependencyItem){
      for(auto& Item:SrcDependency){
        DependencyChain::AddDependency(ArgDependencyItem,Item);
      }
    }else{
      for(auto& Item:SrcDependency){
        DependencyChain::AddDependency(root,Item);
      }
    }
    
    root->UpdateTargetStatus();

    if(postbuild.size()>0){

      std::list<DependencyItem_SystemProcess::Task::Pointer> commandTaskList;
      std::list<std::list<std::string>> argsList;

      for(auto& Value:postbuild){
        std::list<std::string> args;

        for(auto& Item:Value.ValueArray()){
          args.emplace_back(Item);
        }

        argsList.emplace_back(args);
        commandTaskList.emplace_back(DependencyItem_SystemProcess::Task_Process::New(args,io_encoding));
      }
      //标记文件生成
      commandTaskList.emplace_back(DependencyItem_SystemProcess::Task_Thread::New(
        [PostBuildMarkFilePath](std::stringstream& SS,bool ioexclusive){
          auto res=FileUpdateEmpty(PostBuildMarkFilePath);
          SS<<res.second;
          return res.first;
        })
      );

      std::string skipLog;
      std::string runLog;
      SetLogTag(
        runLog,"PostBuild \e[" C_VT_F_Cyan "m"+targetConfig->Name()+"\e[0m",
        skipLog,"SKIP [PostBuild "+targetConfig->Name()+"]",
        argsList
      );

      auto postBuild=DependencyItem_SystemProcess::New(PostBuildMarkFilePath,commandTaskList,runLog,skipLog,log);
      postBuild->SetIOExclusive(true);
      postBuild->UpdateTargetStatus();
      
      DependencyChain::AddDependency(postBuild,root);
      root=postBuild;
    }

    return root;
  }

  DependencyChain::Item::Pointer TargetTask_GCC::MakeSrcTask_CC_CXX_AS(const H::Path& SourcePath,const H::Path& TargetPath,SrcTaskType Type){
    std::string Compiler_Str;
    std::list<std::string>* Compiler;
    std::string TagColorText;

    switch(Type){
      case SrcTaskType::CC:
        Compiler_Str="CC";
        Compiler=&CC;
        TagColorText="\e[" C_VT_F_Yellow "m";
        break;
      case SrcTaskType::CXX:
        Compiler_Str="CXX";
        Compiler=&CXX;
        TagColorText="\e[" C_VT_F_Cyan "m";
        break;
      case SrcTaskType::AS:
        Compiler_Str="AS";
        Compiler=&AS;
        TagColorText="\e[" C_VT_F_Purple "m";
        break;
      default:
        throw std::runtime_error("不识别的源文件类型");
    }


    //CompilerCC -c -std=xxx OPT Define Include dep InFile... -o OutFile
    //CompilerCXX -c -std=xxx OPT Define Include dep InFile... -o OutFile
    //CompilerAS -c -std=xxx OPT Define Include dep InFile... -o OutFile
    std::list<std::string> Args;
    DependencyChain::Item::Pointer ArgDependencyItem;

    if(Compiler->empty()){
      throw std::runtime_error("HMake.Compiler."+Compiler_Str+" 无有效的值");
    }
    for(auto& Item:*Compiler){
      Args.emplace_back(Item);
    }

    Args.emplace_back("-c");

    auto SourcePathStr=SourcePath.String();
    auto TargetPathStr=TargetPath.String();
    auto SourceDependencyPathStr=TargetPathStr+".d";
    auto ArgFilePath=TargetPathStr+".arg";
    TargetPathStr=TargetPathStr+".o";

    auto TargetDirectory=(TargetPath+"../").DiscardRelative();
    auto ObjDirectoryCreateTask=DirectoryCollection->Insert(TargetDirectory,"\e[" C_VT_F_Green "mCreate Directory\e[0m: "+TargetDirectory.String(),"SKIP [Create Directory "+TargetDirectory.String()+"]",log);
    ObjDirectoryCreateTask->UpdateTargetStatus();


    //Standard
    if((Type==SrcTaskType::CC)||(Type==SrcTaskType::CXX)){
      auto Standard=ReadValue_WithPathDefault(targetConfig,"HMake.Compiling."+Compiler_Str+".Standard",SourcePath,cwd);
      if(Standard.length()>0){
        Args.emplace_back("-std="+Standard);
      }
    }

    {
      //opt
      auto Args_Dep=ReadChildAllValue_WithPath(targetConfig,"HMake.Compiling."+Compiler_Str+".Option",SourcePath,cwd);

      //Optimization
      {
        auto Optimization=ReadValue_WithPathDefault(targetConfig,"HMake.Compiling.Optimization",SourcePath,cwd);
        if(Optimization.length()>0){
          Args_Dep.emplace_back("-O"+Optimization);
        }
      }

      //Define
      {
        auto Define=ReadChildAllValue_WithPath(targetConfig,"HMake.Compiling."+Compiler_Str+".Define",SourcePath,cwd);
        for(auto& Item:Define){
          Args_Dep.emplace_back("-D"+Item);
        }
      }

      //Include
      {
        auto PriorIncludeDirectory=ReadChildAllValue_WithPath(targetConfig,"HMake.Compiling."+Compiler_Str+".IncludeDirectory.Prior",SourcePath,cwd);
        auto IncludeDirectory=ReadChildAllValue_WithPath(targetConfig,"HMake.Compiling."+Compiler_Str+".IncludeDirectory",SourcePath,cwd);
        auto SystemIncludeDirectory=ReadChildAllValue_WithPath(targetConfig,"HMake.Compiling."+Compiler_Str+".IncludeDirectory.System",SourcePath,cwd);

        for(auto& Item:PriorIncludeDirectory){
          Args_Dep.emplace_back("-I"+H::Path(Item).DiscardRelative().String());
        }
        for(auto& Item:IncludeDirectory){
          Args_Dep.emplace_back("-iquote"+H::Path(Item).DiscardRelative().String());
        }
        for(auto& Item:SystemIncludeDirectory){
          Args_Dep.emplace_back("-isystem"+H::Path(Item).DiscardRelative().String());
        }
      }

      if(Args_Dep.size()<9){
        Args.splice(Args.end(),Args_Dep);
      }else{
        std::string skipLog;
        if((attribute&AttributeMask::IsPrintSkip)!=0U){
          skipLog="SKIP [Create "+ArgFilePath+"]";
        }
        ArgDependencyItem=DependencyItem_SystemProcess::New(ArgFilePath,DependencyItem_SystemProcess::Task_Thread::New(
          [ArgFilePath,Args_Dep](std::stringstream& SS,bool ioexclusive){
            auto res=CreateParamFile(ArgFilePath,Args_Dep);
            SS<<res.second;
            return res.first;
          }
        ),"",skipLog,log);
        ArgDependencyItem->UpdateTargetStatus();
        DependencyChain::AddDependency(ArgDependencyItem,hmkFileDependency);
        DependencyChain::AddDependency(ArgDependencyItem,ObjDirectoryCreateTask);
        Args.emplace_back("@"+ArgFilePath);
      }
    }

    //Dependency
    Args.emplace_back("-MMD");
    Args.emplace_back("-MP");
    Args.emplace_back("-MF"+SourceDependencyPathStr);

    //InFile
    Args.emplace_back(SourcePathStr);
    
    //OutFile
    Args.emplace_back("-o");
    Args.emplace_back(TargetPathStr);

    std::string skipLog;
    std::string runLog;
    SetLogTag(
      runLog,TagColorText+Compiler_Str+"\e[0m "+SourcePathStr,
      skipLog,"SKIP ["+Compiler_Str+" "+SourcePathStr+"]",
      Args
    );
    auto r=DependencyItem_SystemProcess::New(TargetPathStr,Args,io_encoding,runLog,skipLog,log);

    auto headerDependencyTask=MakeHeaderDependency(SourceDependencyPathStr,SourcePathStr,TargetPathStr);

    DependencyChain::AddDependency(r,ObjDirectoryCreateTask);
    DependencyChain::AddDependency(r,ArgDependencyItem);
    DependencyChain::AddDependency(r,hmkFileDependency);

    auto InputDep=DependencyItem_Input::New(SourcePathStr);
    InputDep->UpdateTargetStatus();
    DependencyChain::AddDependency(r,InputDep);

    for(auto& Item:headerDependencyTask){
      DependencyChain::AddDependency(r,Item);
    }

    r->UpdateTargetStatus();
    return r;
  }

}



